﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Runtime.InteropServices;

using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swcommands;
using SolidWorks.Interop.swconst;
using SolidWorks.Interop.swpublished;

using SwAddinHelpers.Contracts;
using SwAddinHelpers.Attributes;
using SwAddinHelpers;
using SwAddinHelpers.Base;
using SwAddinHelpers.Sinks;
using SwAddinHelpers.ComHelpers;



namespace SwAddinHelpers.FeatureView
{
    [ComVisible(true)]
    [ProgId(PROGID)]
    public sealed class DummyControl : UserControl
    {
        public const string PROGID = "SwAddinHelpers.FeatureView.DummyControl";

        private Label l;

        public DummyControl()
        {
            this.l = new System.Windows.Forms.Label();
            this.SuspendLayout();
           
            this.l.Location = new System.Drawing.Point(10, 10);
            this.l.Name = "label";
            this.l.Size = new System.Drawing.Size(150, 60);
            this.l.TabIndex = 0;
            this.l.Text = "Your Property Pages will be hosted in the other Feature View if you instructed them to do so.";
            
            this.Controls.Add(this.l);
            this.Name = "PMP Host";
            this.ResumeLayout(false);
        }
    }

    public sealed class FeatureViewHost: UserControlHostBase
    {
        private ManagedWinapi.Windows.SystemWindow WindowTabCtl;
        private ManagedWinapi.Windows.SystemWindow WindowTabCtl2;
        private ManagedWinapi.Windows.SystemWindow WindowFvControl;

        public void ActivatePmpHolder()
        {
            try
            {

                if (WindowTabCtl != null)
                {
                    IntPtr ret = IntPtr.Zero;

                    if (_FeatureManagerView2 != null)
                    {

                        ret = pinvoke.SendMessage(WindowTabCtl2.HWnd, pinvoke.TCM_GETCURSEL, IntPtr.Zero, IntPtr.Zero);
                        if (ret.ToInt32() == 1)
                        {
                            foreach (ManagedWinapi.Windows.SystemWindow sw in WindowTabCtl2.AllChildWindows)
                                pinvoke.ShowWindow(sw.HWnd, 0);

                            ret = pinvoke.SendMessage(WindowTabCtl2.HWnd, pinvoke.TCM_DESELECTALL, IntPtr.Zero, IntPtr.Zero);
                            ret = pinvoke.SendMessage(WindowTabCtl2.HWnd, pinvoke.TCM_SETCURSEL, new IntPtr(4), IntPtr.Zero);
                        }

                        _FeatureManagerView2.DeActivateView();
                    }

                    _FeatureManagerView.ActivateView();

                    foreach (ManagedWinapi.Windows.SystemWindow sw in WindowTabCtl.AllChildWindows)
                        pinvoke.ShowWindow(sw.HWnd, 0);

                    // select PMP tab
                    ret = pinvoke.SendMessage(WindowTabCtl.HWnd, pinvoke.TCM_SETCURSEL, new IntPtr(3), IntPtr.Zero);
                }
            }
            catch
            { // catch if no activedocument 
            }

            #region testing
            // get current tab selection
            //ret = SendMessage(WindowTabCtl.HWnd, TCM_GETCURSEL, IntPtr.Zero, IntPtr.Zero);
            
            /*

            NMHDR lp_changing = new NMHDR();
            lp_changing.hwndFrom = WindowTabCtl.HWnd;
            //lp_changing.idFrom = new IntPtr(GetDlgCtrlID(WindowTabCtl.HWnd));
            lp_changing.idFrom = new IntPtr(WindowTabCtl.DialogID);
            lp_changing.code = TCN_SELCHANGING;
            IntPtr lpi_changing = Marshal.AllocHGlobal(Marshal.SizeOf(lp_changing));
            Marshal.StructureToPtr(lp_changing, lpi_changing, false);
            ret = SendMessage(WindowTabCtl.HWnd, WM_NOTIFY, lp_changing.idFrom, lpi_changing);
            Marshal.FreeHGlobal(lpi_changing);

            */
             
            // deselect all tabs
            //ret = SendMessage(WindowTabCtl.HWnd, TCM_DESELECTALL, IntPtr.Zero, IntPtr.Zero);



            /*
            NMHDR lp_change = new NMHDR();
            lp_change.hwndFrom = WindowTabCtl.HWnd;
            //lp_change.idFrom = new IntPtr(GetDlgCtrlID(WindowTabCtl.HWnd));
            lp_change.idFrom = new IntPtr(WindowTabCtl.DialogID);
            lp_change.code = TCN_SELCHANGE;
            IntPtr lpi_change = Marshal.AllocHGlobal(Marshal.SizeOf(lp_change));
            Marshal.StructureToPtr(lp_change, lpi_change, false);
            ret =SendMessage(WindowTabCtl.HWnd, WM_NOTIFY, lp_change.idFrom, lpi_change);
            Marshal.FreeHGlobal(lpi_change);
            */
            #endregion
        }

        private FeatMgrView _FeatureManagerView;
        private FeatMgrView _FeatureManagerView2 = null;
        private bool _IsHost = false;

        public FeatMgrView FeatureManagerView
        {
            get { return _FeatureManagerView; }
        }

        private string _BitmapFile; 
        private string _FeatureViewToolTip;
        private double _SplitterPosition;
        private swFeatMgrPane_e _WhichPane;
        private bool _AutoGenView;
        private bool _NotifyUserOfCreationFailure;

        private FeatureViewHost(ISwAddinBase owner, string BitMapFile, string FeatureViewTooltip, swFeatMgrPane_e WhichPane = swFeatMgrPane_e.swFeatMgrPaneBottom, bool AutoGenerateView = false, double SplitterPosition = 0.5, bool NotifyUserOfCreationFailure = false, bool IsHost = false)
        {
        	_BitmapFile = BitMapFile;
            _IsHost = IsHost;
            _FeatureViewToolTip = FeatureViewTooltip;
            _SplitterPosition = SplitterPosition;
            _WhichPane = WhichPane;
            _AutoGenView = AutoGenerateView;
            _NotifyUserOfCreationFailure = NotifyUserOfCreationFailure;

            _OwnerAddin = owner;

            if (_AutoGenView)
            {
                this.SubscribeEvent(enumEventSink.SW_ActiveModelDocChangeNotify, enumEventSubscriptionSource.GUI_HOST);
                this.SubscribeEvent(enumEventSink.Document_DestroyNotify, enumEventSubscriptionSource.GUI_HOST);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="owner"></param>
        /// <param name="externalControl"></param>
        /// <param name="FeatureViewTooltip"></param>
        /// <param name="WhichPane"></param>
        /// <param name="AutoGenerateView">FeatureView Tab is created/destroyed when active document changes or is destroyed.  The effect is that the FeatureView Tab follows the active document.  Setting this to false means that you have to manually create/delete your FeatureView tab.  This can only be done when there is an active document available.</param>
        /// <param name="SplitterPosition">Set to 0 to show as part of current visible feature view, WhichPane must be TOP.</param>
        public FeatureViewHost(ISwAddinBase owner, IExternalUserControl externalControl, string BitMapFile, string FeatureViewTooltip,
                               swFeatMgrPane_e WhichPane, bool AutoGenerateView, double SplitterPosition, bool NotifyUserOfCreationFailure, bool IsHost)
            : this(owner, BitMapFile, FeatureViewTooltip, WhichPane, AutoGenerateView, SplitterPosition, NotifyUserOfCreationFailure, IsHost)
        {
            base.externalControl = externalControl.ExternalUserControl;
        }

        [SinkMethod(enumEventSink.SW_ActiveModelDocChangeNotify)]
        private void CreateFeatureView(object sender, EventArgs e)
        {
            bool IsCreated  = CreateFeatureView(true);
            if ( _NotifyUserOfCreationFailure && !IsCreated)
            {
                MessageBox.Show("Failed to create feature view tab " + HostedControlTypeProgId + " !");
            }
        }

        public bool CreateFeatureView(bool Activate)
        {   
            DeleteFeatureView();
            
            ModelViewManager modelViewManager = null;
            bool returns = false;

            try
            {
                //string bmp = _OwnerAddin.DUMMYBMP;
                
                if (_BitmapFile=="") _BitmapFile=_OwnerAddin.DUMMYBMP;
                
                

                modelViewManager = _OwnerAddin.SolidWorksApplication.IActiveDoc2.ModelViewManager;
                
                _FeatureManagerView = modelViewManager.CreateFeatureMgrControl2(
                    _BitmapFile,
                    HostedControlTypeProgId,
                    "",
                    _FeatureViewToolTip,
                    (int)_WhichPane);

                _GuiControl = (UserControlBase)_FeatureManagerView.GetControl();

                WindowFvControl = new ManagedWinapi.Windows.SystemWindow(_GuiControl);
                WindowTabCtl = WindowFvControl.Parent.Parent;

                if (_IsHost)
                {
                    swFeatMgrPane_e theOtherPane = swFeatMgrPane_e.swFeatMgrPaneBottom;
                    if (_WhichPane == swFeatMgrPane_e.swFeatMgrPaneBottom) theOtherPane = swFeatMgrPane_e.swFeatMgrPaneTop;
                    _FeatureManagerView2 = modelViewManager.CreateFeatureMgrControl2(_BitmapFile, "SwAddinHelpers.FeatureView.DummyControl", "", "", (int)theOtherPane);
                    WindowTabCtl2 = new ManagedWinapi.Windows.SystemWindow(_FeatureManagerView2.GetControl()).Parent.Parent;
                }

                //ManagedWinapi.Windows.SystemWindow WindowPmpHolderTop = WindowFvControl.Parent.Parent.AllChildWindows.ToList().
                //    Find(delegate(ManagedWinapi.Windows.SystemWindow r) { return r.Title == "uiVisualSketchEditorView_c"; });
                //WindowPmpHolder = WindowPmpHolderTop.AllChildWindows.ToList().
                //    Find(delegate(ManagedWinapi.Windows.SystemWindow r) { return r.Title == "Dve sheet"; });
                //

                _GuiControl.SetOwner = this;
                if (_GuiControl != null) _GuiControl.Tie();

                _OwnerAddin.SolidWorksApplication.IActiveDoc2.FeatureManagerSplitterPosition = _SplitterPosition;

                if (Activate) _FeatureManagerView.ActivateView();

                returns = true;
            }
            catch 
            {
                returns = false;
            }
            finally
            {
                Marshal.ReleaseComObject(modelViewManager);
            }

            return returns;
        }

        [SinkMethod(enumEventSink.Document_DestroyNotify)]
        private void DeleteFeatureView(object sender, SolidWorksEventArgs e)
        {
            DeleteFeatureView();
        }

        public void DeleteFeatureView()
        {
            
            if (_FeatureManagerView != null)
            {
                if (_GuiControl != null)
                {
                    _GuiControl.Untie();
                    _GuiControl = null;
                }


                try
                {
                    _FeatureManagerView.DeActivateView(); 
                    _FeatureManagerView.DeleteView();
                }
                catch (SEHException seh)
                {

                }
                    

                try { Marshal.ReleaseComObject(_FeatureManagerView.GetControl()); }
                catch { }

                Marshal.ReleaseComObject(_FeatureManagerView);
                _FeatureManagerView = null;

                if (_FeatureManagerView2 != null)
                {

                    try
                    {
                        _FeatureManagerView2.DeActivateView();
                        _FeatureManagerView2.DeleteView();
                    }
                    catch (SEHException seh)
                    {

                    }

                    try { Marshal.ReleaseComObject(_FeatureManagerView2.GetControl()); }
                    catch { }

                    Marshal.ReleaseComObject(_FeatureManagerView2);
                    _FeatureManagerView2 = null;
                }

                try
                {
                    _OwnerAddin.SolidWorksApplication.IActiveDoc2.FeatureManagerSplitterPosition = 0f;
                }
                catch { }
            }

            WindowTabCtl = null;
            WindowTabCtl2 = null;
            WindowFvControl = null;
           
        }

        public override void Teardown()
        {
            base.Teardown();

            DeleteFeatureView();
        }

    }
}
